top.Event.prototype.stop=Event.prototype.stop=function(){try{
	this.preventDefault();
	this.stopPropagation();
}catch(e){trace(e);}};

/* quick tests :
(listeners.add("foo",function(evt){alert("3"+evt.data); evt.stop();},20));
(listeners.add("foo",function(evt){alert("4"+evt.data);},30));
alert(listeners.listeners.toSource());
listeners.send("foo","Hello");
alert(listeners.getWithWildcard("foo",undefined,0).toSource());
*/

window.listeners={
	Listener:function(type,callback,priority){try{
		this.type=type.toLowerCase();
		this.callback=callback;
		this.priority=typeof(priority)=="number"?priority:65536;
	}catch(e){trace(e);}},
	listeners:{},
	
	add:function(type,callback,priority,dontOverwrite){try{
		type=type.toLowerCase();
		
		if(!dontOverwrite){
			var existing=window.listeners.getWithWildcard(type,callback,priority);
			for(var i=0;i<existing.length;i++)
				window.listeners.delByIndex(existing[i].type,existing[i].index);
		}
		
		if(!window.listeners.listeners[type])
			window.listeners.listeners[type]=[];
			
		var listener=new window.listeners.Listener(type,callback,priority);
		window.listeners.listeners[type].push(listener);
		
		return listener;
	}catch(e){trace(e);}},
	
	del:function(listener){try{
		var i=listener.type;
		
		for(var j=0;j<window.listeners.listeners[i].length;j++){
			if(window.listeners.listeners[i][j]==listener){
				listeners.delByIndex(listener.type,j);
				return;
			}
		}
	}catch(e){trace(e);}},
	
	delByIndex:function(type,index){try{
		type=type.toLowerCase();
		if(!window.listeners.listeners[type] || index>=window.listeners.listeners[type].length)
			return;
		
		window.listeners.listeners[type].splice(index,1);
	}catch(e){trace(e);}},
	
	getWithWildcard:function(type,callback,priority){try{
		var rList=[];
		
		if(typeof(type)=="undefined"){
			var enumObject=window.listeners.listeners;
		}else{
			var enumObject={};
			enumObject[type.toLowerCase()]=true;
		}
		
		for(var i in enumObject){
			if(!window.listeners.listeners[i])
				continue;
			
			for(var j=window.listeners.listeners[i].length-1;j>=0;j--){
				if(
				  ( typeof(callback)=="undefined" || window.listeners.listeners[i][j].callback==callback )
				  &&
				  ( typeof(priority)=="undefined" || window.listeners.listeners[i][j].priority==priority )
				){
					rList.push({listener:window.listeners.listeners[i][j],type:i,index:j});
				}
			}
		}
		
		return rList;
	}catch(e){trace(e);}},
	
	send:function(type,data){try{
		type=type.toLowerCase();
		if(!window.listeners.listeners[type] || !window.listeners.listeners[type].length)
			return;
		
		var copy=window.listeners.listeners[type].slice(0);
		copy.sort( function(a, b) a.priority-b.priority );
		
		var evt={
			type : type,
			data : data,
			evt : null,
			stop : function() this.stopped=true
		};
		
		for(var i=0;i<copy.length;i++){
			evt.listener=copy[i];
			
			copy[i].callback(evt);
			if(evt.stopped)
				return evt;
		}
		
		return evt;
	}catch(e){trace(e);}},
};